using UnityEngine;
using System.Collections;

public class Enemy_Controller : MonoBehaviour
{
	public static CharacterController CharacterController;
	public static Enemy_Controller Instance;
	public EnemyState State {get; set;}
	
	private EnemyState lastState;
	
	public EnemyDirection MoveDirection {get; set;}
	bool IsDead  {get; set;}
	
	public LevelStatus levelStateMachine;
	public Transform targetPlayer;
	
	//Store random value for direction in Idle
	public float EnemyIdleStateRandomizer = 0f;
	//Store ranges for player Detection
	public float PlayerDetectionRange = 20.0f;
	public float MeleeAttackRange = 2.0f;
	//Attack variables
	public int damage = 1;


	
	Vector3 runDirection;
	
	public float attackRunSpeed = 5.0f;
	public float attackRotateSpeed = 20.0f;
	
	//Amount of time to remain idle
	public float idleTime = 1.6f;
	
	//Attack direction and radius
	public Vector3 attackPosition = new Vector3(0.4f, 0.0f, 0.7f);
	public float attackRadius = 1.1f;
	
	//Sounds
	//Played during idle state
	public AudioClip idleSound;
	//Played during the seek and attack modes
	public AudioClip attackSound;
	
	private float attackAngle = 10.0f;
	private bool isAttacking = false;
	private float lastAttackTime = 0.0f;
	
	
	//Enemy States
	public enum EnemyState
	{
		Idle, Combat, Running, Attacking, Dead, GetHit, ActionLocked
	}
	
	//Movement Direction
	public enum EnemyDirection
	{
		Stationary, Forward	
	}
		
	void Awake()
	{
		Instance = this;
		
		CheckLevelStatus();
		
		//Initialize the EnemyState
		State = EnemyState.Idle;
	}
		
	void Update()
	{
		//Decide which state and actions to perform
		DetermineEnemyState();
		ProcessEnemyState();
		Debug.Log("Enemy State: " + State.ToString());

	}
	
	void DetermineEnemyState()
	{
		if(State == EnemyState.Dead)
		{
			return;	
		}

//		//Running in a specific direction
//		if(State != EnemyState.Attacking &&
//		   State != EnemyState.Combat )
//		{
//			switch(MoveDirection)
//			{
//			case EnemyDirection.Stationary:
//				State = EnemyState.Idle;
//				break;
//			case EnemyDirection.Forward:
//				State = EnemyState.Running;
//				break;
//
//			}
//		}
	}
	//If the enemy is idle, determine where to move
	void GetIdleLocomotionDirection()
	{
		EnemyIdleStateRandomizer = Random.value;
		
		if(EnemyIdleStateRandomizer >= 0.0f && EnemyIdleStateRandomizer < 0.2f)
		{
			//Move Forward
		}
		else if(EnemyIdleStateRandomizer >= 0.2f && EnemyIdleStateRandomizer < 0.4f)
		{
			//Move Left
		}
		else if(EnemyIdleStateRandomizer >= 0.4f && EnemyIdleStateRandomizer < 0.6f)
		{
			//Move Right
		}
		else if(EnemyIdleStateRandomizer >= 0.6f && EnemyIdleStateRandomizer < 0.8f)
		{
			//Move Backwards
		}
		else
		{
			//Play Idle or Combat animation
		}
	}
	
	void ProcessEnemyState()
	{
		switch (State)
		{
		case EnemyState.Idle:
			Idle();
			break;
		case EnemyState.Running:
			Running();
			break;
		case EnemyState.Attacking:
			Attacking();
			break;
		case EnemyState.Combat:
			InCombat();
			break;
		case EnemyState.Dead:
			Dying();
			break;
		case EnemyState.GetHit:
			GetHit();
			break;
		case EnemyState.ActionLocked:
			break;
		}
	}
	
	//Rotate towards Player
	public float RotateTowardsPosition(Vector3 targetPos, float rotateSpeed)
	{
		//Compute relative point and get the angle towards it
		Vector3 relative = transform.InverseTransformPoint(targetPos);
		float angle = Mathf.Atan2(relative.x, relative.z) * Mathf.Rad2Deg;
		
		//Clamp it with the max rotation speed
		float maxRotation = rotateSpeed * Time.deltaTime;
		float clampedAngle = Mathf.Clamp(angle, -maxRotation, maxRotation);
		
		//Rotate
		transform.Rotate(0f, clampedAngle, 0f);
		//Return the current angle
		return angle;
	}
	
	#region Player State Functions
	void Idle()
	{
		GetIdleLocomotionDirection();
		animation.CrossFade("Idle");
		DetectPlayerRange();
		
	}
	
	void Attack()
	{
		Debug.Log("Attacking");
		//Already attacking
		if(State == EnemyState.Attacking)
		{
			return;	
		}
		
		//Set lastState
		lastState = State;
		//Set State
		State = EnemyState.Attacking;
		//Play animation
		animation.CrossFade("Attacking");
	}
	
	void Run()
	{
		if(State == EnemyState.Running)
		{
			return;	
		}
		
		lastState = State;
		State = EnemyState.Running;
		//animation["Running"].weight = animation["Running"].speed = attackRunSpeed;
		animation["Running"].wrapMode = WrapMode.Loop;
		animation.CrossFade("Running");
	}
	
	void EnterCombat()
	{
		//Already in combat
		if(State == EnemyState.Combat)
		{
			return;	
		}
		lastState = State;
		State = EnemyState.Combat;
		animation.CrossFade("Combat");
	}
	
	void Die()
	{
		Dying();
		animation.CrossFade("Dead");
	}
	
	void GetHit()
	{
		State = EnemyState.GetHit;
		animation.CrossFade("GetHit");
	}
	#endregion
	#region Enemy Recovery Functions
	void Dying()
	{
		IsDead = true;
		State = EnemyState.Dead;
	}
	
	void InCombat()
	{
		
		//Combat animation is playing
		if(!animation.isPlaying)
		{
			//Run towards player now
			Run();
			
		}
		else
		{
			RotateToFacePlayer();	
		}
		
		
	}
	
	void Attacking()
	{
		if(!animation.isPlaying)
		{
			if(lastState == EnemyState.Idle)
			{
				State = EnemyState.Idle;
				animation.CrossFade("Idle");		
			}
			else if(lastState == EnemyState.Combat)
			{
				State = EnemyState.Combat;
				animation.CrossFade("Combat");
			}
			else if(lastState == EnemyState.Running)
			{
				State = EnemyState.Running;
				animation.CrossFade("Running");
			}	
		}
	}
	
	void Running()
	{
		Debug.Log("Reached Running State");
		
		if(!animation.isPlaying)
		{
			if(lastState == EnemyState.Idle)
			{
				State = EnemyState.Idle;
				animation.CrossFade("Idle");		
			}
			else if(lastState == EnemyState.Combat)
			{
				State = EnemyState.Combat;
				animation.CrossFade("Combat");
			}
			else if(lastState == EnemyState.Attacking)
			{
				State = EnemyState.Running;
				animation.CrossFade("Attacking");
			}	
		}
		else
		{
			//Still running	transform.TransformDirection
			runDirection = ( (targetPlayer.position - transform.position));
			CharacterController.SimpleMove(runDirection);
			RotateToFacePlayer();
			CheckMeleeRange();
		}
	}
	#endregion
	//If Player is in range, Enter Combat
	void DetectPlayerRange()
	{
		if((Vector3.Distance(targetPlayer.transform.position, transform.position) < PlayerDetectionRange))
		{
			EnterCombat();	
		}
	}
	
	void RotateToFacePlayer()
	{
		//Turn to face the player
		transform.LookAt(new Vector3(targetPlayer.position.x, transform.position.y, targetPlayer.position.z));
	}
	
	void CheckMeleeRange()
	{
		if((Vector3.Distance(targetPlayer.transform.position, transform.position) < MeleeAttackRange))
		{
			Attack();	
		}
		else
		{
			//EnterCombat();
		}
		Debug.Log("Checked Melee Range");
		
	}
	void CheckLevelStatus()
	{
		levelStateMachine = GameObject.Find("/Level_Status").GetComponent<LevelStatus>();
		CharacterController = GetComponent<CharacterController>();
		
		//Check for LevelStatus script
		if(!levelStateMachine)
		{
			Debug.Log("EnemyMonster: ERROR! NO LEVEL STATUS SCRIPT FOUND");
		}
		
		//Check for playerCharacter Script and set as target
		if(!targetPlayer)
		{
			targetPlayer = GameObject.FindWithTag("Player").transform;		
		}
	}
}

